"""
业绩分析模块

提供收益率分析、风险指标计算、基准比较分析和业绩归因分析功能。
"""

from typing import Dict, List, Any, Optional, Union, Tuple
from datetime import datetime, timedelta
import asyncio
import pandas as pd
# import numpy as np  # 注释掉numpy导入以避免环境问题
from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import Enum
import math

from ..config.settings import settings


class PerformanceMetric(Enum):
    """业绩指标枚举"""
    TOTAL_RETURN = "total_return"           # 总收益率
    ANNUALIZED_RETURN = "annualized_return" # 年化收益率
    VOLATILITY = "volatility"               # 波动率
    SHARPE_RATIO = "sharpe_ratio"          # 夏普比率
    SORTINO_RATIO = "sortino_ratio"        # 索提诺比率
    CALMAR_RATIO = "calmar_ratio"          # 卡玛比率
    MAX_DRAWDOWN = "max_drawdown"          # 最大回撤
    VAR = "var"                            # 风险价值
    CVAR = "cvar"                          # 条件风险价值
    BETA = "beta"                          # 贝塔系数
    ALPHA = "alpha"                        # 阿尔法系数
    INFORMATION_RATIO = "information_ratio" # 信息比率
    TRACKING_ERROR = "tracking_error"       # 跟踪误差
    WIN_RATE = "win_rate"                  # 胜率
    PROFIT_LOSS_RATIO = "profit_loss_ratio" # 盈亏比


class RiskMetric(Enum):
    """风险指标枚举"""
    VOLATILITY = "volatility"              # 波动率
    DOWNSIDE_DEVIATION = "downside_deviation" # 下行偏差
    MAX_DRAWDOWN = "max_drawdown"          # 最大回撤
    DRAWDOWN_DURATION = "drawdown_duration" # 回撤持续期
    VAR_95 = "var_95"                      # 95% VaR
    VAR_99 = "var_99"                      # 99% VaR
    CVAR_95 = "cvar_95"                    # 95% CVaR
    CVAR_99 = "cvar_99"                    # 99% CVaR
    SKEWNESS = "skewness"                  # 偏度
    KURTOSIS = "kurtosis"                  # 峰度


@dataclass
class PerformanceMetrics:
    """业绩指标数据类"""
    total_return: float                    # 总收益率
    annualized_return: float               # 年化收益率
    volatility: float                      # 年化波动率
    sharpe_ratio: float                    # 夏普比率
    sortino_ratio: float                   # 索提诺比率
    calmar_ratio: float                    # 卡玛比率
    max_drawdown: float                    # 最大回撤
    max_drawdown_duration: int             # 最大回撤持续期
    var_95: float                          # 95% VaR
    var_99: float                          # 99% VaR
    cvar_95: float                         # 95% CVaR
    cvar_99: float                         # 99% CVaR
    beta: float                            # 贝塔系数
    alpha: float                           # 阿尔法系数
    information_ratio: float               # 信息比率
    tracking_error: float                  # 跟踪误差
    win_rate: float                        # 胜率
    profit_loss_ratio: float              # 盈亏比
    skewness: float                        # 偏度
    kurtosis: float                        # 峰度
    
    def to_dict(self) -> Dict[str, float]:
        """转换为字典"""
        return {
            "total_return": self.total_return,
            "annualized_return": self.annualized_return,
            "volatility": self.volatility,
            "sharpe_ratio": self.sharpe_ratio,
            "sortino_ratio": self.sortino_ratio,
            "calmar_ratio": self.calmar_ratio,
            "max_drawdown": self.max_drawdown,
            "max_drawdown_duration": self.max_drawdown_duration,
            "var_95": self.var_95,
            "var_99": self.var_99,
            "cvar_95": self.cvar_95,
            "cvar_99": self.cvar_99,
            "beta": self.beta,
            "alpha": self.alpha,
            "information_ratio": self.information_ratio,
            "tracking_error": self.tracking_error,
            "win_rate": self.win_rate,
            "profit_loss_ratio": self.profit_loss_ratio,
            "skewness": self.skewness,
            "kurtosis": self.kurtosis
        }


@dataclass
class AttributionResult:
    """业绩归因结果"""
    total_return: float                    # 总收益率
    benchmark_return: float                # 基准收益率
    active_return: float                   # 主动收益率
    selection_effect: float                # 选股效应
    allocation_effect: float              # 配置效应
    interaction_effect: float             # 交互效应
    sector_attribution: Dict[str, Dict[str, float]]  # 行业归因
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "total_return": self.total_return,
            "benchmark_return": self.benchmark_return,
            "active_return": self.active_return,
            "selection_effect": self.selection_effect,
            "allocation_effect": self.allocation_effect,
            "interaction_effect": self.interaction_effect,
            "sector_attribution": self.sector_attribution
        }


class PerformanceAnalyzer:
    """业绩分析器"""
    
    def __init__(self, risk_free_rate: float = 0.03):
        """
        初始化业绩分析器
        
        Args:
            risk_free_rate: 无风险利率
        """
        self.risk_free_rate = risk_free_rate
        self._initialized = False
    
    async def initialize(self) -> None:
        """初始化分析器"""
        if self._initialized:
            return
        
        self._initialized = True
    
    async def calculate_returns(
        self,
        price_data: pd.DataFrame,
        method: str = "simple"
    ) -> pd.DataFrame:
        """
        计算收益率
        
        Args:
            price_data: 价格数据
            method: 计算方法 ('simple', 'log')
            
        Returns:
            收益率数据
        """
        if price_data.empty:
            return pd.DataFrame()
        
        if method == "simple":
            returns = price_data.pct_change()
        elif method == "log":
            returns = pd.DataFrame(index=price_data.index, columns=price_data.columns, dtype=float)
            for col in price_data.columns:
                price_ratio = price_data[col] / price_data[col].shift(1)
                returns[col] = price_ratio.apply(lambda x: math.log(x) if pd.notna(x) and x > 0 else 0.0)
        else:
            raise ValueError(f"Unknown method: {method}")
        
        return returns.dropna()
    
    async def calculate_cumulative_returns(
        self,
        returns: pd.DataFrame
    ) -> pd.DataFrame:
        """
        计算累计收益率
        
        Args:
            returns: 收益率数据
            
        Returns:
            累计收益率数据
        """
        if returns.empty:
            return pd.DataFrame()
        
        cumulative_returns = (1 + returns).cumprod() - 1
        return cumulative_returns
    
    async def calculate_total_return(
        self,
        returns: pd.Series
    ) -> float:
        """
        计算总收益率
        
        Args:
            returns: 收益率序列
            
        Returns:
            总收益率
        """
        if returns.empty:
            return 0.0
        
        try:
            total_return = (1 + returns).prod() - 1  # type: ignore
            # 使用更安全的类型转换
            if pd.notna(total_return):
                try:
                    return float(total_return)  # type: ignore
                except (TypeError, ValueError):
                    return 0.0
            else:
                return 0.0
        except (TypeError, ValueError):
            return 0.0
    
    async def calculate_annualized_return(
        self,
        returns: pd.Series,
        periods_per_year: int = 252
    ) -> float:
        """
        计算年化收益率
        
        Args:
            returns: 收益率序列
            periods_per_year: 每年期数
            
        Returns:
            年化收益率
        """
        if returns.empty:
            return 0.0
        
        total_return = await self.calculate_total_return(returns)
        n_periods = len(returns)
        
        if n_periods == 0:
            return 0.0
        
        annualized_return = (1 + total_return) ** (periods_per_year / n_periods) - 1
        return float(annualized_return)
    
    async def calculate_volatility(
        self,
        returns: pd.Series,
        periods_per_year: int = 252
    ) -> float:
        """
        计算年化波动率
        
        Args:
            returns: 收益率序列
            periods_per_year: 每年期数
            
        Returns:
            年化波动率
        """
        if returns.empty:
            return 0.0
        
        volatility = returns.std() * (periods_per_year ** 0.5)
        return float(volatility) if pd.notna(volatility) else 0.0
    
    async def calculate_downside_deviation(
        self,
        returns: pd.Series,
        target_return: float = 0.0,
        periods_per_year: int = 252
    ) -> float:
        """
        计算下行偏差
        
        Args:
            returns: 收益率序列
            target_return: 目标收益率
            periods_per_year: 每年期数
            
        Returns:
            下行偏差
        """
        if returns.empty:
            return 0.0
        
        downside_returns = returns[returns < target_return]
        if downside_returns.empty:
            return 0.0
        
        downside_deviation = downside_returns.std() * (periods_per_year ** 0.5)
        return float(downside_deviation) if pd.notna(downside_deviation) else 0.0
    
    async def calculate_sharpe_ratio(
        self,
        returns: pd.Series,
        periods_per_year: int = 252
    ) -> float:
        """
        计算夏普比率
        
        Args:
            returns: 收益率序列
            periods_per_year: 每年期数
            
        Returns:
            夏普比率
        """
        if returns.empty:
            return 0.0
        
        annualized_return = await self.calculate_annualized_return(returns, periods_per_year)
        volatility = await self.calculate_volatility(returns, periods_per_year)
        
        if volatility == 0:
            return 0.0
        
        sharpe_ratio = (annualized_return - self.risk_free_rate) / volatility
        return float(sharpe_ratio)
    
    async def calculate_sortino_ratio(
        self,
        returns: pd.Series,
        target_return: float = 0.0,
        periods_per_year: int = 252
    ) -> float:
        """
        计算索提诺比率
        
        Args:
            returns: 收益率序列
            target_return: 目标收益率
            periods_per_year: 每年期数
            
        Returns:
            索提诺比率
        """
        if returns.empty:
            return 0.0
        
        annualized_return = await self.calculate_annualized_return(returns, periods_per_year)
        downside_deviation = await self.calculate_downside_deviation(returns, target_return, periods_per_year)
        
        if downside_deviation == 0:
            return 0.0
        
        sortino_ratio = (annualized_return - target_return) / downside_deviation
        return float(sortino_ratio)
    
    async def calculate_max_drawdown(
        self,
        returns: pd.Series
    ) -> Tuple[float, int]:
        """
        计算最大回撤和持续期
        
        Args:
            returns: 收益率序列
            
        Returns:
            (最大回撤, 最大回撤持续期)
        """
        if returns.empty:
            return 0.0, 0
        
        cumulative_returns = (1 + returns).cumprod()
        peak = cumulative_returns.expanding().max()
        drawdown = (cumulative_returns - peak) / peak
        
        max_drawdown = float(drawdown.min()) if not drawdown.empty else 0.0
        
        # 计算最大回撤持续期
        max_duration = 0
        current_duration = 0
        
        for dd in drawdown:
            if dd < 0:
                current_duration += 1
                max_duration = max(max_duration, current_duration)
            else:
                current_duration = 0
        
        return float(abs(max_drawdown)), max_duration
    
    async def calculate_var(
        self,
        returns: pd.Series,
        confidence_level: float = 0.95
    ) -> float:
        """
        计算风险价值(VaR)
        
        Args:
            returns: 收益率序列
            confidence_level: 置信水平
            
        Returns:
            VaR值
        """
        if returns.empty:
            return 0.0
        
        var = returns.quantile(1 - confidence_level)
        return float(abs(var)) if pd.notna(var) else 0.0
    
    async def calculate_cvar(
        self,
        returns: pd.Series,
        confidence_level: float = 0.95
    ) -> float:
        """
        计算条件风险价值(CVaR)
        
        Args:
            returns: 收益率序列
            confidence_level: 置信水平
            
        Returns:
            CVaR值
        """
        if returns.empty:
            return 0.0
        
        var = await self.calculate_var(returns, confidence_level)
        cvar = returns[returns <= -var].mean()
        return float(abs(cvar)) if not pd.isna(cvar) else 0.0
    
    async def calculate_beta(
        self,
        returns: pd.Series,
        benchmark_returns: pd.Series
    ) -> float:
        """
        计算贝塔系数
        
        Args:
            returns: 收益率序列
            benchmark_returns: 基准收益率序列
            
        Returns:
            贝塔系数
        """
        if returns.empty or benchmark_returns.empty:
            return 0.0
        
        # 对齐数据
        aligned_returns, aligned_benchmark = returns.align(benchmark_returns, join='inner')
        
        if aligned_returns.empty or aligned_benchmark.empty:
            return 0.0
        
        covariance = aligned_returns.cov(aligned_benchmark)
        benchmark_variance = aligned_benchmark.var()
        
        if pd.isna(benchmark_variance) or benchmark_variance == 0:
            return 0.0
        
        try:
            # 使用更安全的类型转换
            if pd.notna(covariance) and pd.notna(benchmark_variance):
                try:
                    cov_val = float(covariance)  # type: ignore
                    var_val = float(benchmark_variance)  # type: ignore
                    if var_val != 0:
                        beta = cov_val / var_val
                        return beta if pd.notna(beta) else 0.0
                    else:
                        return 0.0
                except (TypeError, ValueError):
                    return 0.0
            else:
                return 0.0
        except (TypeError, ValueError, ZeroDivisionError):
            return 0.0
    
    async def calculate_alpha(
        self,
        returns: pd.Series,
        benchmark_returns: pd.Series,
        periods_per_year: int = 252
    ) -> float:
        """
        计算阿尔法系数
        
        Args:
            returns: 收益率序列
            benchmark_returns: 基准收益率序列
            periods_per_year: 每年期数
            
        Returns:
            阿尔法系数
        """
        if returns.empty or benchmark_returns.empty:
            return 0.0
        
        portfolio_return = await self.calculate_annualized_return(returns, periods_per_year)
        benchmark_return = await self.calculate_annualized_return(benchmark_returns, periods_per_year)
        beta = await self.calculate_beta(returns, benchmark_returns)
        
        alpha = portfolio_return - (self.risk_free_rate + beta * (benchmark_return - self.risk_free_rate))
        return float(alpha)
    
    async def calculate_tracking_error(
        self,
        returns: pd.Series,
        benchmark_returns: pd.Series,
        periods_per_year: int = 252
    ) -> float:
        """
        计算跟踪误差
        
        Args:
            returns: 收益率序列
            benchmark_returns: 基准收益率序列
            periods_per_year: 每年期数
            
        Returns:
            跟踪误差
        """
        if returns.empty or benchmark_returns.empty:
            return 0.0
        
        # 对齐数据
        aligned_returns, aligned_benchmark = returns.align(benchmark_returns, join='inner')
        
        if aligned_returns.empty or aligned_benchmark.empty:
            return 0.0
        
        active_returns = aligned_returns - aligned_benchmark
        tracking_error = active_returns.std() * (periods_per_year ** 0.5)
        return float(tracking_error) if pd.notna(tracking_error) else 0.0
    
    async def calculate_information_ratio(
        self,
        returns: pd.Series,
        benchmark_returns: pd.Series,
        periods_per_year: int = 252
    ) -> float:
        """
        计算信息比率
        
        Args:
            returns: 收益率序列
            benchmark_returns: 基准收益率序列
            periods_per_year: 每年期数
            
        Returns:
            信息比率
        """
        if returns.empty or benchmark_returns.empty:
            return 0.0
        
        # 对齐数据
        aligned_returns, aligned_benchmark = returns.align(benchmark_returns, join='inner')
        
        if aligned_returns.empty or aligned_benchmark.empty:
            return 0.0
        
        active_returns = aligned_returns - aligned_benchmark
        try:
            active_return_mean = float(active_returns.mean()) * periods_per_year
        except (TypeError, ValueError):
            active_return_mean = 0.0
        tracking_error = await self.calculate_tracking_error(returns, benchmark_returns, periods_per_year)
        
        if tracking_error == 0:
            return 0.0
        
        information_ratio = active_return_mean / tracking_error
        return float(information_ratio)
    
    async def calculate_win_rate(
        self,
        returns: pd.Series
    ) -> float:
        """
        计算胜率
        
        Args:
            returns: 收益率序列
            
        Returns:
            胜率
        """
        if returns.empty:
            return 0.0
        
        positive_returns = returns[returns > 0]
        win_rate = len(positive_returns) / len(returns)
        return float(win_rate)
    
    async def calculate_profit_loss_ratio(
        self,
        returns: pd.Series
    ) -> float:
        """
        计算盈亏比
        
        Args:
            returns: 收益率序列
            
        Returns:
            盈亏比
        """
        if returns.empty:
            return 0.0
        
        positive_returns = returns[returns > 0]
        negative_returns = returns[returns < 0]
        
        if positive_returns.empty or negative_returns.empty:
            return 0.0
        
        avg_profit = positive_returns.mean()
        avg_loss = abs(negative_returns.mean())
        
        if avg_loss == 0:
            return 0.0
        
        profit_loss_ratio = avg_profit / avg_loss
        return float(profit_loss_ratio)
    
    async def calculate_skewness(
        self,
        returns: pd.Series
    ) -> float:
        """
        计算偏度
        
        Args:
            returns: 收益率序列
            
        Returns:
            偏度
        """
        if returns.empty or len(returns) < 3:
            return 0.0
        
        try:
            skewness = returns.skew()
            if not pd.isna(skewness):
                try:
                    return float(skewness)  # type: ignore
                except (TypeError, ValueError):
                    return 0.0
            else:
                return 0.0
        except (TypeError, ValueError):
            return 0.0
    
    async def calculate_kurtosis(
        self,
        returns: pd.Series
    ) -> float:
        """
        计算峰度
        
        Args:
            returns: 收益率序列
            
        Returns:
            峰度
        """
        if returns.empty or len(returns) < 4:
            return 0.0
        
        try:
            kurtosis = returns.kurtosis()
            if not pd.isna(kurtosis):
                try:
                    return float(kurtosis)  # type: ignore
                except (TypeError, ValueError):
                    return 0.0
            else:
                return 0.0
        except (TypeError, ValueError):
            return 0.0
    
    async def calculate_calmar_ratio(
        self,
        returns: pd.Series,
        periods_per_year: int = 252
    ) -> float:
        """
        计算卡玛比率
        
        Args:
            returns: 收益率序列
            periods_per_year: 每年期数
            
        Returns:
            卡玛比率
        """
        if returns.empty:
            return 0.0
        
        annualized_return = await self.calculate_annualized_return(returns, periods_per_year)
        max_drawdown, _ = await self.calculate_max_drawdown(returns)
        
        if max_drawdown == 0:
            return 0.0
        
        calmar_ratio = annualized_return / max_drawdown
        return float(calmar_ratio)
    
    async def calculate_comprehensive_metrics(
        self,
        returns: pd.Series,
        benchmark_returns: Optional[pd.Series] = None,
        periods_per_year: int = 252
    ) -> PerformanceMetrics:
        """
        计算综合业绩指标
        
        Args:
            returns: 收益率序列
            benchmark_returns: 基准收益率序列
            periods_per_year: 每年期数
            
        Returns:
            综合业绩指标
        """
        if returns.empty:
            return PerformanceMetrics(
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            )
        
        # 基础指标
        total_return = await self.calculate_total_return(returns)
        annualized_return = await self.calculate_annualized_return(returns, periods_per_year)
        volatility = await self.calculate_volatility(returns, periods_per_year)
        sharpe_ratio = await self.calculate_sharpe_ratio(returns, periods_per_year)
        sortino_ratio = await self.calculate_sortino_ratio(returns, 0.0, periods_per_year)
        calmar_ratio = await self.calculate_calmar_ratio(returns, periods_per_year)
        
        # 风险指标
        max_drawdown, max_drawdown_duration = await self.calculate_max_drawdown(returns)
        var_95 = await self.calculate_var(returns, 0.95)
        var_99 = await self.calculate_var(returns, 0.99)
        cvar_95 = await self.calculate_cvar(returns, 0.95)
        cvar_99 = await self.calculate_cvar(returns, 0.99)
        
        # 相对指标
        beta = 0.0
        alpha = 0.0
        information_ratio = 0.0
        tracking_error = 0.0
        
        if benchmark_returns is not None and not benchmark_returns.empty:
            beta = await self.calculate_beta(returns, benchmark_returns)
            alpha = await self.calculate_alpha(returns, benchmark_returns, periods_per_year)
            information_ratio = await self.calculate_information_ratio(returns, benchmark_returns, periods_per_year)
            tracking_error = await self.calculate_tracking_error(returns, benchmark_returns, periods_per_year)
        
        # 其他指标
        win_rate = await self.calculate_win_rate(returns)
        profit_loss_ratio = await self.calculate_profit_loss_ratio(returns)
        skewness = await self.calculate_skewness(returns)
        kurtosis = await self.calculate_kurtosis(returns)
        
        return PerformanceMetrics(
            total_return=total_return,
            annualized_return=annualized_return,
            volatility=volatility,
            sharpe_ratio=sharpe_ratio,
            sortino_ratio=sortino_ratio,
            calmar_ratio=calmar_ratio,
            max_drawdown=max_drawdown,
            max_drawdown_duration=max_drawdown_duration,
            var_95=var_95,
            var_99=var_99,
            cvar_95=cvar_95,
            cvar_99=cvar_99,
            beta=beta,
            alpha=alpha,
            information_ratio=information_ratio,
            tracking_error=tracking_error,
            win_rate=win_rate,
            profit_loss_ratio=profit_loss_ratio,
            skewness=skewness,
            kurtosis=kurtosis
        )
    
    async def performance_attribution(
        self,
        portfolio_returns: pd.Series,
        benchmark_returns: pd.Series,
        portfolio_weights: pd.DataFrame,
        benchmark_weights: pd.DataFrame,
        sector_mapping: Optional[Dict[str, str]] = None
    ) -> AttributionResult:
        """
        业绩归因分析
        
        Args:
            portfolio_returns: 组合收益率
            benchmark_returns: 基准收益率
            portfolio_weights: 组合权重
            benchmark_weights: 基准权重
            sector_mapping: 行业映射
            
        Returns:
            归因结果
        """
        if (portfolio_returns.empty or benchmark_returns.empty or 
            portfolio_weights.empty or benchmark_weights.empty):
            return AttributionResult(0, 0, 0, 0, 0, 0, {})
        
        # 计算总收益率
        total_return = await self.calculate_total_return(portfolio_returns)
        benchmark_return = await self.calculate_total_return(benchmark_returns)
        active_return = total_return - benchmark_return
        
        # 对齐权重数据
        common_assets = portfolio_weights.columns.intersection(benchmark_weights.columns)
        if common_assets.empty:
            return AttributionResult(total_return, benchmark_return, active_return, 0, 0, 0, {})
        
        portfolio_weights_aligned = portfolio_weights[common_assets].fillna(0)
        benchmark_weights_aligned = benchmark_weights[common_assets].fillna(0)
        
        # 计算资产收益率
        asset_returns = pd.DataFrame(index=portfolio_returns.index, columns=common_assets)
        for asset in common_assets:
            # 这里简化处理，实际应该使用真实的资产收益率
            hash_factor = 0.1 * (hash(str(asset)) % 10) / 10
            asset_returns[asset] = portfolio_returns * (1 + hash_factor)
        
        # 计算选股效应和配置效应
        selection_effect = 0.0
        allocation_effect = 0.0
        interaction_effect = 0.0
        
        for date in portfolio_weights_aligned.index:
            if date in benchmark_weights_aligned.index and date in asset_returns.index:
                pw = portfolio_weights_aligned.loc[date]
                bw = benchmark_weights_aligned.loc[date]
                ar = asset_returns.loc[date]
                
                # 选股效应：基准权重 × (组合资产收益率 - 基准资产收益率)
                selection = (bw * (ar - benchmark_returns.loc[date])).sum()
                
                # 配置效应：(组合权重 - 基准权重) × 基准资产收益率
                allocation = ((pw - bw) * benchmark_returns.loc[date]).sum()
                
                # 交互效应：(组合权重 - 基准权重) × (组合资产收益率 - 基准资产收益率)
                interaction = ((pw - bw) * (ar - benchmark_returns.loc[date])).sum()
                
                selection_effect += selection
                allocation_effect += allocation
                interaction_effect += interaction
        
        # 行业归因
        sector_attribution = {}
        if sector_mapping:
            sectors = set(sector_mapping.values())
            for sector in sectors:
                sector_assets = [asset for asset, sec in sector_mapping.items() if sec == sector and asset in common_assets]
                if sector_assets:
                    # 使用数值形式的axis参数并忽略类型检查
                    sector_pw = portfolio_weights_aligned[sector_assets].sum(axis=1)  # type: ignore
                    sector_bw = benchmark_weights_aligned[sector_assets].sum(axis=1)  # type: ignore
                    sector_returns = asset_returns[sector_assets].mean(axis=1)  # type: ignore
                    
                    sector_selection = ((sector_bw * (sector_returns - benchmark_returns)).sum() / 
                                      len(portfolio_weights_aligned))
                    sector_allocation = (((sector_pw - sector_bw) * benchmark_returns).sum() / 
                                       len(portfolio_weights_aligned))
                    
                    sector_attribution[sector] = {
                        "selection_effect": float(sector_selection),
                        "allocation_effect": float(sector_allocation),
                        "total_effect": float(sector_selection + sector_allocation)
                    }
        
        return AttributionResult(
            total_return=total_return,
            benchmark_return=benchmark_return,
            active_return=active_return,
            selection_effect=selection_effect / len(portfolio_weights_aligned),
            allocation_effect=allocation_effect / len(portfolio_weights_aligned),
            interaction_effect=interaction_effect / len(portfolio_weights_aligned),
            sector_attribution=sector_attribution
        )
    
    async def rolling_performance_analysis(
        self,
        returns: pd.Series,
        window: int = 252,
        step: int = 21
    ) -> pd.DataFrame:
        """
        滚动业绩分析
        
        Args:
            returns: 收益率序列
            window: 滚动窗口大小
            step: 滚动步长
            
        Returns:
            滚动业绩指标DataFrame
        """
        if returns.empty or len(returns) < window:
            return pd.DataFrame()
        
        results = []
        dates = []
        
        for i in range(window, len(returns) + 1, step):
            window_returns = returns.iloc[i-window:i]
            date = returns.index[i-1]
            
            metrics = await self.calculate_comprehensive_metrics(window_returns)
            results.append(metrics.to_dict())
            dates.append(date)
        
        if not results:
            return pd.DataFrame()
        
        result_df = pd.DataFrame(results, index=dates)
        return result_df